#define __GAME_CPP__

#include "AI.h"

void AI::Menu(AI*& ai)
{
Again:
    printf("\e[1;1H\e[2J");
    printf("##################################\n");
    printf("##################################\n");
    printf("#####   0.NORMAL      1.AI   #####\n");
    printf("##################################\n");
    printf("##################################\n");
    printf("Please Select# ");
    int select = 0;
    scanf("%d", &select);
    if (select == 1)
        ai = GetHeapAI();
    else if (select == 0)
        ai = nullptr;
    else
        goto Again;
}

AI::AI()
{
    memset(score, 0, ROW * COL * sizeof(score[0][0]));
}

AI* AI::GetHeapAI(void)
{
    return new AI;
}

int ChessCount(int board[ROW][COL], int row, int col, int X, int Y, enum Dir dir, char* boundry)
{
    int count = 0;
    int _x = X - 1;
    int _y = Y - 1;
    for (int num = 0; num < 4; num++)
    {
        switch (dir)
        {
            case LEFT :
                _y--;
                        break;
            case RIGHT :
                _y++;
                        break;
            case UP :
                _x--;
                        break;
            case DOWN :
                _x++;
                        break;
            case LEFT_UP :
                _x--, _y--;
                        break;
            case RIGHT_DOWN :
                _x++, _y++;
                        break;
            case LEFT_DOWN :
                _x++, _y--;
                        break;
            case RIGHT_UP :
                _x--, _y++;
                        break;
            default :
                        break;
        }
        if ((_x < 0 || _x >= row) || (_y < 0 || _y >= col))
        {
            *boundry = 1;
            break;
        }
        if (board[_x][_y] == board[X - 1][Y - 1])
            count++;
        else
        {
            if (board[_x][_y] != EMPTY)
                *boundry = 1;
            break;
        }
    }
    return count;
}

//对棋子的边界分数判定函数,单独提取出来
int CountAstrict(int board[ROW][COL], int row, int col, int X, int Y, enum Dir dir)
{
    char boundry[2] = { 0  };
    int left = ChessCount(board, row, col, X + 1, Y + 1, dir, boundry);
    int right = ChessCount(board, row, col, X + 1, Y + 1, (enum Dir)(dir + 1), boundry + 1);

    if (left + right >= 4)
        return left + right;
    if (boundry[0] + boundry[1] == 2)
        return 0;
    else
        return left + right - boundry[0] - boundry[1];
}

void AI::AIScoreAward(int board[ROW][COL], int row, int col, int X, int Y, enum Dir dir)
{
    int num = 0;
    for (int i = 1; i <= 2; i++)
    {
        board[X][Y] = i;
        int tmp = CountAstrict(board, row, col, X, Y, dir);
        if (tmp > num)
            num = tmp;
    }
    board[X][Y] = EMPTY;
    double mul = 1.0;
    switch (num)
    {
        case 0 :
            score[X][Y] += 0;
                    break;
        case 1 :
            if (score[X][Y] > 100)
                mul = 1.1;
            score[X][Y] += 10;
                    break;
        case 2 :
            if (score[X][Y] > 50)
                mul = 1.3;
            score[X][Y] += 30;
                    break;
        case 3 :
            if (score[X][Y] > 10)
                mul = 1.5;
            score[X][Y] += 80;
                    break;
        case 4 :
        case 5 :
        case 6 :
        case 7 :
        case 8 :
            if (score[X][Y] > 10)
                mul = 2;
            score[X][Y] += 200;
                    break;
        case -1 :
        case -2 :
            score[X][Y] -= 20;
                    break;
        default : 
                    break;
    }
    score[X][Y] *= mul;
}

AI::XY AI::AIMove(int board[ROW][COL], int row, int col)
{
    AI::XY ret;
    int maxscore = 0;
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            score[i][j] = 0;
            if (board[i][j] == EMPTY)
            {
                for (int dir = 0; dir < 8; dir += 2)
                    AIScoreAward(board, row, col, i, j, (enum Dir)dir);
            }
            else
                score[i][j] = -100;
            if (score[i][j] >= maxscore)
                maxscore = score[i][j], ret.x = i + 1, ret.y = j + 1;
        }
    }
    return ret;
}

#undef __GAME_CPP__
